package com.itaming.lycheeframework.jackson.sensitive;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.itaming.lycheeframework.support.utils.DesensitizationUtil;

import java.io.IOException;

/**
 * 脱敏序列化器
 *
 * @author A.Ming
 */
public class DesensitizedSerializer extends JsonSerializer<String> implements ContextualSerializer {

    /**
     * 注解
     */
    private Sensitive annotation;

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty.getType().hasRawClass(String.class)) {
            Sensitive annotation = beanProperty.getAnnotation(Sensitive.class);
            if (annotation == null) {
                annotation = beanProperty.getContextAnnotation(Sensitive.class);
            }
            if (annotation != null) {
                this.annotation = annotation;
                return this;
            }
        }
        return serializerProvider.findValueSerializer(String.class, beanProperty);
    }

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 没有注解，使用默认序列化器
        if (this.annotation == null) {
            serializers.findValueSerializer(String.class).serialize(value, gen, serializers);
        }

        // 脱敏处理
        String desensitizedValue = switch (this.annotation.type()) {
            case CUSTOM ->
                DesensitizationUtil.desensitize(value, this.annotation.startIndex(), this.annotation.endIndex(), this.annotation.mask());
            case ADDRESS -> DesensitizationUtil.address(value, this.annotation.mask());
            case BANK_CARD -> DesensitizationUtil.bankCard(value, this.annotation.mask());
            case CAR_LICENSE -> DesensitizationUtil.carLicense(value, this.annotation.mask());
            case CHINESE_ID -> DesensitizationUtil.chineseId(value, this.annotation.mask());
            case CHINESE_MOBILE -> DesensitizationUtil.chineseMobile(value, this.annotation.mask());
            case EMAIL -> DesensitizationUtil.email(value, this.annotation.mask());
            case IPV4 -> DesensitizationUtil.ipv4(value, this.annotation.mask());
            case IPV6 -> DesensitizationUtil.ipv6(value, this.annotation.mask());
            case NAME -> DesensitizationUtil.name(value, this.annotation.mask());
            case PASSWORD -> DesensitizationUtil.password(value, this.annotation.mask());
        };

        gen.writeString(desensitizedValue);
    }

}
